#pragma once

#include <iostream>
#include <memory>

#include "Socket.hpp"
#include "Connection.hpp"
#include "Epoller.hpp"
#include "Channel.hpp"

using namespace SocketModule;

class Listener : public Connection
{
public:
    Listener(int port = 8080) : _port(port),
                                _listensock(std::make_unique<TcpSocket>())
    {
        _listensock->BindTcpSocketMethod(_port); // 创建绑定监听一条龙

        SetEvents(EPOLLIN | EPOLLET);   // 设置关心读事件
        SetNonBlock(_listensock->Fd()); // 设置获取fd非阻塞
    }

    void Sender() override {}                               // 发送数据虚函数重写, 无实际内容
    void Excepter() override {}                             // 异常处理虚函数重写, 无实际内容
    int GetSockFd() override { return _listensock->Fd(); }; // 获取sockfd虚函数重写


    // 接收数据虚函数重写, listenscok -> accept
    void Recver() override
    {
        // LOG(LogLevel::DEBUG) << "Listener::Recver";

        InetAddr client;
        while (true)
        {
            int sockfd = _listensock->Accept(&client); // 接收连接请求
            if (sockfd == ACCEPT_DONE)
                break; // 底层已无数据可读
            else if (sockfd == ACCEPT_CONTINUE)
                continue; // 接收被信号中断
            else if (sockfd == ACCEPT_ERROR)
                break; // 错误
            else
            {
                // 成功读取普通fd
                // 创建Connection子类Channel
                std::shared_ptr<Connection> conn = std::make_unique<Channel>(sockfd, client);
                conn->SetEvents(EPOLLIN | EPOLLET); // 设置关心读事件
                if(_handler != nullptr)
                    conn->RegsiterHandler(_handler); // Listener将事件处理函数注册进Channel中

                GetOwner()->AddConnection(conn); // 将该Channel加入Reactor管理
            }
        }
    }

    ~Listener() {}

private:
    int _port;                           // 监听端口号
    std::unique_ptr<Socket> _listensock; // 监听套接字
};